package com.cicadamob.contact.api.Utils;



import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnKeyListener;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * 耗时操作
 * @author wang
 *
 * @param <T>
 */

abstract public class ProgressExecutor<T> {



	private static final String TAG = "PE";
	
	public static final int MESSAGE_WHAT_OK			= 0;
	public static final int MESSAGE_WHAT_CANCEL 	= 1;
	public static final int MESSAGE_WHAT_EXCEPTION 	= 9;
	
	/**
	 * 处理类
	 */
	public static final Handler handler = new ProgressHandler();
	
	private Context context;
	private Dialog progressDialog;
	
	private boolean isOnCancel;
	private boolean isShowDialog;
	
	public ProgressExecutor(Context context) {
		this.context 	= context;
		this.isOnCancel	= false;
		this.isShowDialog = true;
	}
	
	/**
	 * 关联的Activity
	 * @return
	 */
	public Context getContext() {
		return context;
	}
	
	/**
	 * 长时间操作实现方法
	 * @throws Exception
	 */
	abstract public T execute() throws Exception;
	
	/**
	 * 返回结果的正常处理
	 * @param t
	 */
	abstract public void doResult(T t);
	
	/**
	 * 取消操作
	 * */
	public void onCancel() {
		//Toast.makeText(getContext(), "取消操作", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * 设置是否取消
	 * */
	public void setCancel(boolean b) {
		isOnCancel = b;
	}
	
	/**
	 * 返回结果的异常处理
	 * @param ex
	 */
	public void doException(Exception ex) {
		Log.d(TAG, "异常", ex);
		if(context != null) {
			Toast.makeText(getContext(), ex.getMessage(), Toast.LENGTH_SHORT).show();
		}
	}
	
	/**
	 * 是否异步执行
	 * @return
	 */
	public boolean isAsync() {
		return true;
	}
	
	/**
	 * 是否显示进度条
	 * @return
	 */
	public boolean isShowProgressDialog() {
		return isShowDialog;
	}
	
	/**
	 * 设置是否显示进度条
	 * @param b true=显示, 否则不显示
	 * */
	public void setShowProgressDialog(boolean b) {
		isShowDialog = b;
	}
	
	/**
	 * 进度对话框
	 * @return
	 */
	public Dialog getProgressDialog() {
		if(context != null && progressDialog == null) {
			progressDialog = new DefaultProgressDialog(context);
			progressDialog.setCanceledOnTouchOutside(false);
			progressDialog.setCancelable(true);
			progressDialog.setOnDismissListener(new OnDismissListener() {
				
				@Override
				public void onDismiss(DialogInterface dialog) {
					dialog.dismiss();
					setCancel(true);
				}
			});
			progressDialog.setOnKeyListener(new OnKeyListener() {
				
				@Override
				public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
					dialog.dismiss();
					setCancel( true);
					return false;
				}
			});
		}
		return progressDialog;
	}
	
	private void syncExecute() {
		Message msg = new Message();
		msg.setTarget(handler);
		//执行长时间操作
		Object result 	= null;
		try {
			Log.i(TAG, "start............." + isOnCancel);
			result 		= execute();
			Log.i(TAG, "execute end......." + isOnCancel);
			msg.what 	= (isOnCancel)? MESSAGE_WHAT_CANCEL : MESSAGE_WHAT_OK;
		} catch(Exception e) {
			result 		= e;
			msg.what 	= MESSAGE_WHAT_EXCEPTION;
		}
		msg.obj 		= new Object[] { this, result };
		
		//关闭进度条
		closeDialog();
		
		//处理返回结果
		msg.sendToTarget();
	}
	
	/**
	 * 执行
	 */
	public void start() {
		//显示进度条
		showDialog();
		if(isAsync()) {	//异步执行
			Thread async = new Thread() {
				public void run() {
					Looper.prepare();
					syncExecute();
					Looper.loop();
				}
			};
			async.start();
		} else {		
			syncExecute();
		}
	}
	
	/**
	 * 显示执行进度条
	 */
	private void showDialog() {
		if(isShowProgressDialog()) {
			progressDialog = getProgressDialog();
			if(progressDialog != null) {
				progressDialog.show();
			}
		}
	}
	
	/**
	 * 关闭进度条
	 */
	private void closeDialog() {
		if(isShowProgressDialog()) {
			if(progressDialog != null && progressDialog.isShowing()) {
				progressDialog.dismiss();
			}
		}
	}
	
	/**
	 * 处理类
	 * @author xzh
	 *
	 */
	private static class ProgressHandler extends Handler {

		@SuppressWarnings({ "rawtypes", "unchecked" })
		@Override
		public void handleMessage(Message msg) {
			Object[] objs = (Object[])msg.obj;
			ProgressExecutor exe = (ProgressExecutor)objs[0];
			Object result = objs[1];
			switch(msg.what) {
				case MESSAGE_WHAT_OK:
					exe.doResult(result);
					break;
				case MESSAGE_WHAT_EXCEPTION:
					exe.doException((Exception)result);
					break;
				case MESSAGE_WHAT_CANCEL:
					exe.setCancel(false);
					Log.i(TAG, "msg get cancel.......");
					exe.onCancel();
					break;
				default:
					break;
			}
			
		}
		
	}
	
	/**
	 * 自定义的ProgressDialog
	 * @author xzh
	 *
	 */
	public static class DefaultProgressDialog extends AlertDialog {
		private int layoutId;
		public DefaultProgressDialog(Context context, int themeId, int layoutId) {
			super(context, themeId);
			this.layoutId = layoutId;
		}
		
		public DefaultProgressDialog(Context context) {
			super(context);
		}

		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			if(layoutId != 0) {
				setContentView(layoutId);
			}
			setCanceledOnTouchOutside(false);
			setCancelable(false);
			
			ProgressBar bar = new ProgressBar(getContext());
			setContentView(bar);
			ViewParent vp = bar.getParent();
			while(vp != null) {
				ViewParent vp0 = vp.getParent();
				if(vp0 == null) {
					if(vp instanceof View) {
						//((View)vp).setBackgroundColor(Color.LTGRAY);
					}
					break;
				} else {
					vp = vp0;
				}
			}
//			((View)bar.getParent().getParent().getParent()).setBackgroundColor(Color.LTGRAY);
			/**设置透明度*/
			Window window = getWindow();
			WindowManager.LayoutParams lp = window.getAttributes();
			lp.alpha = 1f;// 透明度
			lp.dimAmount = 0f;// 黑暗度
			window.setAttributes(lp); 
			window.getDecorView().setBackgroundResource(Color.TRANSPARENT);
		}
		
	}





}
